#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# (c) Copyright 2008 Rudá Moura. All Rights Reserved. 
#

"""Handle IPv4 subnetwork.

Classes:
  - IpSubnet.

Examples:
   >>> net = IpSubnet("192.168.0.0")
   >>> print net
   192.168.0.0/255.255.255.0
   >>> print net.match("192.168.0.128")
   True
   >>> print net.match("192.168.1.0")
   False
"""

import sys

class IpSubnet(object):
    "Class to simulate ip network operations."

    def __init__(self, ip, mask_or_bits="24"):
        self.set_ip(ip)
        self.set_mask_or_bits(mask_or_bits)
        
    def __str__(self):
        ip = [str(x) for x in self.ip]
        mask = [str(x) for x in self.mask]
        return "%s/%s" % (".".join(ip), ".".join(mask))

    def __eq__(self, other):
        return (self.ip == other.ip) and (self.mask == other.mask)
    
    def __neq__(self, other):
        return (self.ip != other.ip) or (self.mask != other.mask)
        
    def set_ip(self, ip):
        self.ip = [int(x) for x in ip.split(".")]
    
    def set_mask_or_bits(self, mask_or_bits):
        if '.' not in mask_or_bits:
            bits = "1" * int(mask_or_bits)
            bits = bits + ("0" * (32 - len(bits)))
            self.mask = [int(bits[0:8], 2), 
                int(bits[8:16], 2), 
                int(bits[16:24], 2), 
                int(bits[24:], 2)]
        else:
            self.mask = [int(x) for x in mask_or_bits.split(".")]
    
    def match(self, ip):
        "Test if some given IP matches in subnetwork."
        ip = [int(x) for x in (ip.split("."))]
        if ((ip[0] & self.mask[0]) == self.ip[0]) and \
            ((ip[1] & self.mask[1]) == self.ip[1]) and \
            ((ip[2] & self.mask[2]) == self.ip[2]) and \
            ((ip[3] & self.mask[3]) == self.ip[3]):
            return True
        else:
            return False

def match(subnet_or_mask, ip):
    "Test (return True or False) if some ip matches in given subnetwork"
    if ' ' in subnet_or_mask:
        subnet, mask = subnet_or_mask.split(' ')
    elif '/' in subnet_or_mask:
        subnet, mask = subnet_or_mask.split('/')
    else:
        raise 'Invalid format'
    subnet = IpSubnet(subnet, mask)
    return subnet.match(ip)

def _test():
    import doctest
    doctest.testmod()
    
if __name__ == "__main__":
    if len(sys.argv) != 3:
        print "Usage:"
        print "\t", sys.argv[0], "<ipsubnetwork> <ip>"
        print "\t", sys.argv[0], "'192.168.0.0 255.255.255.0' 192.168.0.1"
        print "\t", sys.argv[0], "192.168.0.0/24 192.168.1.1"
        sys.exit(2)
    m = match(sys.argv[1], sys.argv[2])
    if match:
        print "Matched."
        sys.exit(0)
    else:
        print "Not mached."
        sys.exit(1)
